package cn.com.zcode.exam.dao;

import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;

import cn.com.zcode.core.dao.BaseHibernateDaoSupport;
import cn.com.zcode.exam.model.Examination;
import cn.com.zcode.exam.model.Paper;
import cn.com.zcode.exam.model.Question;
import cn.com.zcode.exam.model.StaticInfo;
import cn.com.zcode.exam.model.Wrong;

public class ExamDaoImpl extends BaseHibernateDaoSupport implements ExamDao {

	public synchronized Question saveQuestion(Question question) {
		if (question.getNo() == null) {
			Integer maxid = this.getByHQL("select max(no)+1 from Question", Integer.class);
			question.setNo(maxid == null ? 1 : maxid);
		}
		this.save(question);
		return question;
	}

	@Override
	public List<Question> findQuestions(String pmp) {
		return this.findByHQL("from Question ", Question.class);
	}

	@Override
	public Paper getPaper(String pid) {
		return this.getByHQL("from Paper where id = ?", Paper.class, pid);
	}

	@Override
	public List<Paper> findPapers(String key, String userid) {
		String hql = "from Paper where type = ? and (userId = ? or state= ?)";
		return this.findByHQL(hql, Paper.class, key, userid, Paper.STATE_PUBLIC);
	}

	@Override
	public Wrong getWrong(String userId, String questionId) {
		return this.getByHQL("from Wrong where questionId=? and userId=?", Wrong.class, questionId, userId);
	}

	@Override
	public List<Question> findWrongQuestions(String type, String userId) {
		String hql = "SELECT new Question(q,w) FROM Question q , Wrong w,User u , Dictionary d WHERE  w.userId = u.id  AND u.id =  ? AND q.id = w.questionId "
				+ "AND w.fixed = false  AND d.code = q.chapter  AND d.parent  = ( select d2  from Dictionary d2 where d2.code = ? ) order by d.scort asc,q.id asc ";
		List<Question> list = this.findByHQL(hql, Question.class, userId, type);
		return list;
	}

	@Override
	public List<StaticInfo> findStatinfo(String string) {
		String sql = "SELECT new cn.com.zcode.exam.model.StaticInfo(q.chapter, count(q.chapter)) FROM "
				+ " Wrong e, Question q,Dictionary d where e.questionId = q.id and d.code = q.chapter GROUP BY q.chapter order by d.scort asc";
		Query query = this.getSession().createQuery(sql);
		@SuppressWarnings("unchecked")
		List<StaticInfo> result = query.list();
		return result;
	}

	@Override
	public Paper getPaper(String type, String title, int state, String userid) {
		if (state == 0) {
			return this.getByHQL("from Paper p where p.type = ? and p.title = ? and  p.state=0)", Paper.class, type, title);
		} else {
			return this.getByHQL("from Paper p where p.type = ? and p.title = ? and  p.state=? and p.userId = ?)", Paper.class, type, title, state, userid);
		}
	}

	@Override
	public List<StaticInfo> getPaperInfo(String type) {
		String hql = "SELECT new cn.com.zcode.exam.model.StaticInfo(d.title, count(q.chapter)) "
				+ " FROM Question q,Dictionary d WHERE	q.ptype = ? and	d.code =q.chapter GROUP BY	q.chapter  ORDER BY	d.scort ASC";

		return this.findByHQL(hql, StaticInfo.class, type);
	}

	@Override
	public List<Question> searchQuestions(String keyword, String userId) {
		String hql = "select q from Question q ,PQConnector pq,Paper p where p.id = pq.paperId and q.id = pq.questionId and p.state!=? and (p.userId = ? or p.state=?) and ( q.cnSummary like ? or q.enSummary like ? or q.no=?)";
		keyword = keyword.trim();
		String kparm = "%" + keyword + "%";
		int id = 0;
		if (Pattern.matches("^\\d+$", keyword)) {
			id = Integer.parseInt(keyword);
		}
		return this.findByHQL(hql, Question.class, Paper.STATE_WRONG, userId, Paper.STATE_PUBLIC, kparm, kparm, id);
	}

	@Override
	public Question getQuestion(String id) {
		String hql = "from Question where id = ?";
		return this.getByHQL(hql, Question.class, id);
	}

	@Override
	public List<Examination> findExamination(String key, String userid) {
		String sql = "select e.id,p.id as paperId,p.title,p.type,p.state from exam_paper p "
				+ "left JOIN exam_examination e on p.id = e.paperId and e.endTime is null and e.userId = :userid "
				+ "where p.type = :ptype and (p.userId =:userid or p.state= :pstate)  ";
		SQLQuery sqlquery = this.getSession().createSQLQuery(sql);
		sqlquery.setResultTransformer(Transformers.aliasToBean(Examination.class));
		sqlquery.setParameter("ptype", key);
		sqlquery.setParameter("userid", userid);
		sqlquery.setParameter("pstate", Paper.STATE_PUBLIC);
		return sqlquery.list();
	}

	@Override
	public List<Question> findNewExamQuestions(String pid) {
		String hql = "select q from Question q ,PQConnector pq where pq.questionId = q.id and pq.paperId = ? ";
		return this.findByHQL(hql, Question.class, pid);
	}

	@Override
	public List<Question> findLastExamQuestions(String eid) {
		String hql = "select q from Question q, Examination e,PQConnector pq  where q.id = pq.questionId and pq.paperId = e.paperId and e.id = ? and q.id not in (select a.questionId from Answer a where a.examId=? )";
		return this.findByHQL(hql, Question.class, eid, eid);
	}

	@Override
	public void saveFinishExamination(String eid) {
		String hql = " Update Examination set endTime = :endTime where id = :eid";
		Query query = this.getSession().createQuery(hql);
		query.setParameter("endTime", new Date());
		query.setParameter("eid", eid);
		query.executeUpdate();
		
	}

}
